<?php

namespace app\logic\common;

class L_plugins
{
    /**
     * 获取已安装的插件
     * @param string $paramObj
     */
    public function getInstalledPluginsPage($paramObj = "")
    {
        $dataObj = paramsObj();
        $dataObj->request = paramsObj();
        $dataObj->data = paramsObj();
        $dataObj->data->use_trans = false;
        $dataObj->result = array();

        $final_arr = logInit();
        if ($final_arr["error_no"] == 0) {
            $mixed = parseToArr($paramObj, "mixed", 0);
            $params = parseToArr($paramObj, "params", array());
            $messages = parseToArr($paramObj, "messages", array());
            $rules = array(
                'page' => '',
                'pageSize' => '',
                'name' => '',
            );
            $dataDefault = array();
            $dataDefault["page"]=1;
            $dataDefault["pageSize"]=20;
            $paramsObj = paramsObj();
            $paramsObj->params = $params;
            $paramsObj->mixed = $mixed;
            $paramsObj->rules = $rules;
            $paramsObj->messages = $messages;
            $paramsObj->dataDefault = $dataDefault;
            $checkResult = app("verifyParam")::validatorRequest($paramsObj);
            if ($checkResult["error_no"] == 0) {
                $dataObj->request = $checkResult["result"];
            } else {
                $final_arr = logCallErrorMsg($final_arr, $checkResult);
            }
        }
        if ($final_arr["error_no"] == 0) {
            $paramsObj=paramsObj();
            $paramsObj->params=array(
                "name"=>$dataObj->request->name,
            );
            $checkResult=$this->getInstalledPlugins($paramsObj);
            if ($checkResult["error_no"] == 0) {
                $plugins = $checkResult["result"];
                $install=array();
                if($plugins){
                    foreach($plugins as $val){
                        $install[]=array(
                            "id"=>$val["goodId"],
                            "name"=>$val["name"],
                            "description"=>$val["description"],
                            "pluginData"=>array(
                                "id"=>$val["id"],
                                "pluginDir"=>$val["pluginDir"],
                                "setting"=>$val["setting"],
                                "install"=>1,
                            ),
                        );
                    }
                }
                //生成分页结构
                $final_arr["result"]=$this->pageMake($install,$dataObj->request->page,$dataObj->request->pageSize);
            } else {
                $final_arr = logCallErrorMsg($final_arr, $checkResult);
            }
        }
        return $final_arr;
    }

    /**
     * 获取已安装的插件
     * @param string $paramObj
     */
    public function getInstalledPlugins($paramObj = "")
    {
        $dataObj = paramsObj();
        $dataObj->request = paramsObj();
        $dataObj->data = paramsObj();
        $dataObj->data->use_trans = false;
        $dataObj->result = array();

        $final_arr = logInit();
        if ($final_arr["error_no"] == 0) {
            $mixed = parseToArr($paramObj, "mixed", 0);
            $params = parseToArr($paramObj, "params", array());
            $messages = parseToArr($paramObj, "messages", array());
            $rules = array(
                'name' => '',
            );
            $dataDefault = array();
            $paramsObj = paramsObj();
            $paramsObj->params = $params;
            $paramsObj->mixed = $mixed;
            $paramsObj->rules = $rules;
            $paramsObj->messages = $messages;
            $paramsObj->dataDefault = $dataDefault;
            $checkResult = app("verifyParam")::validatorRequest($paramsObj);
            if ($checkResult["error_no"] == 0) {
                $dataObj->request = $checkResult["result"];
            } else {
                $final_arr = logCallErrorMsg($final_arr, $checkResult);
            }
        }
        if ($final_arr["error_no"] == 0) {
            //获取插件目录下的所有插件目录，检测对应的开启状态,加载开启的插件
            $directory = LTCMS_ROOT . '/plugins';
            $folders = glob($directory . '/*', GLOB_ONLYDIR);
            $install=array();
            $loadPlugin=array();
            // 遍历文件夹数组并输出
            foreach ($folders as $folder) {
                $info=$folder."/info.json";
                $load=$folder."/load";
                if(is_file($info) || is_file($load)){
                    $loadPlugin[]=$folder;
                }
            }
            if($loadPlugin){
                foreach($loadPlugin as $plugin){
                    //检测是否启动
                    $config=$plugin . "/config.php";
                    if(is_file($config)){
                        include_once $config;
                        $classNamespace = str_replace(LTCMS_ROOT . "/", "", $plugin)."/config";
                        $classNamespace = str_replace("/", "\\", $classNamespace);
                        if (class_exists($classNamespace)) {
                            $controllerObj = new $classNamespace;
                            if (method_exists($controllerObj, "info")) {
                                $configInfo = $controllerObj->info();
                                $join=1;
                                if($dataObj->request->name){
                                    if(stripos($configInfo["name"],$dataObj->request->name)===false){
                                        $join=0;
                                    }
                                }
                                if($join=="1"){
                                    $pluginDir=basename($plugin);
                                    $install[$pluginDir]=array(
                                        "id"=>isset($configInfo["id"])?(is_numeric($configInfo["id"])?$configInfo["id"]:0):0,
                                        "goodId"=>isset($configInfo["goodId"])?(is_numeric($configInfo["goodId"])?$configInfo["goodId"]:0):0,
                                        "name"=>isset($configInfo["name"])?$configInfo["name"]:"",
                                        "description"=>isset($configInfo["description"])?$configInfo["description"]:"",
                                        "pluginDir"=>$pluginDir,
                                        "setting"=>array(
                                            "status"=>isset($configInfo["status"])?$configInfo["status"]:"0",
                                            "setUpView"=>isset($configInfo["setUpView"])?$configInfo["setUpView"]:"",
                                        ),
                                    );
                                }
                            }
                        }
                    }
                }
            }
            $final_arr["result"]=$install;
        }
        return $final_arr;
    }

    /**
     * 格式化分页
     * @param $data
     * @return array
     */
    public function pageMake($data,$page,$pageSize)
    {
        $pageLength=10;
        $total=count($data);
        if($total > 0){
            $totalPage=floor(($total-1)/$pageSize)+1;
            $index=$page;
            if($index>$totalPage)
            {
                $index=$totalPage;
            }

            $firstPage=$index-floor($pageLength/2);
            if($firstPage<=0)
            {
                $firstPage=1;
            }

            $lastPage=$firstPage + $pageLength-1;
            if($lastPage > $totalPage)
            {
                $lastPage=$totalPage;
                $firstPage=($totalPage-$pageLength) >0?$totalPage-$pageLength+1:1;
            }

            $offset=($page - 1) * $pageSize;

            $result=array_slice($data,$offset,$pageSize);
            $data=array();
            $data["page"]=$index;
            $data["total"]=$total;
            $data["totalPage"]=$totalPage;
            $data["lastPage"]=$lastPage;
            $data["firstPage"]=$firstPage;
            $data["data"]=$result;
            return $data;
        }
        return array();
    }

    /**
     * 获取已启用的插件
     * @param string $paramObj
     */
    public function getEnabledPlugins($paramObj = "")
    {
        $final_arr = logInit();
        if ($final_arr["error_no"] == 0) {
            $pluginsSettingPath = runtimePath("cache/plugin") . "all.json";
            if (!is_file($pluginsSettingPath) || filesize($pluginsSettingPath) == 0) {
                if (app("P_file")->mkdir(dirname($pluginsSettingPath))) {
                    $data = array();
                    $directory = LTCMS_ROOT . '/plugins'; // 指定插件目录的路径
                    // 使用glob函数获取指定目录下的所有文件夹
                    $folders = glob($directory . '/*', GLOB_ONLYDIR);
                    // 遍历文件夹数组并输出
                    foreach ($folders as $folder) {
                        if (is_file($folder . "/config.php")) {   //存在这个文件则目录为插件目录
                            include_once $folder . "/config.php";
                            $pluginDir = str_replace(LTCMS_ROOT . "/plugins/", "", $folder);
                            $info = array("id" => 0); //直接放的没有id
                            if (is_file($folder . "/info.json")) {
                                $info = file_get_contents($folder . "/info.json");
                                $info = toJsonDecode($info, array());
                            }

                            $config = array();
                            $classNamespace = str_replace(LTCMS_ROOT . "/", "", $folder);
                            $classNamespace .= "/config";
                            $classNamespace = str_replace("/", "\\", $classNamespace);


                            if (class_exists($classNamespace)) {
                                $controllerObj = new $classNamespace;
                                if (method_exists($controllerObj, "info")) {
                                    $config = $controllerObj->info();
                                }
                            }

                            if (isset($info["id"])) {
                                $temp = array_path($config, "setUpView", array());
                                $temp["enable"] = isset($temp["enable"]) ? $temp["enable"] : 2;
                                $temp["width"] = isset($temp["width"]) ? $temp["width"] : 660;
                                $temp["height"] = isset($temp["height"]) ? $temp["height"] : 720;
                                $data[] = array(
                                    "id" => $info["id"],
                                    "pluginDir" => "plugins/" . $pluginDir,
                                    "setUpView" => $temp
                                );
                            }
                        }
                    }
                    $dataJson = toJsonEncode($data);
                    //检测文件夹状态，如果不存在则创建文件夹。
                    if (env()->get("APP_debug", "") == 1) {
                        //调试模式跳过缓存
                    } else {
                        file_put_contents($pluginsSettingPath, $dataJson);
                    }
                    $final_arr["result"] = $data;
                } else {
                    $final_arr = recordLogMsgLevelTwo(app("errorLevel")::E_WARNING, app("errorCode")::OPEN_FAIL, lang("sys.openFail"));
                }
            } else {
                $content = file_get_contents($pluginsSettingPath);
                $final_arr["result"] = $content ? toJsonDecode($content) : array();
            }
        }
        return $final_arr;
    }

    /**
     * 获取已启用的插件 带当前插件状态信息
     * @param string $paramObj
     */
    function getEnabledPlugins2()
    {
        $final_arr = logInit();
        $checkResult = $this->getEnabledPlugins();
        if ($checkResult["error_no"] == 0) {
            $pluginsList = array();
            foreach ($checkResult["result"] as $k => $v) {
                $pluginsList[$v["id"]] = $v;
                $ret = $this->getPluginsStatus(getParamsObj(null, ["pluginId" => $v["pluginDir"]]));
                if ($ret["error_no"] == 0) {
                    $pluginsList[$v["id"]]["status"] = $ret["result"]["status"] ?? 1; //如果没有状态,就直接为启用,可能就是简单或内部插件,只有安装卸载,安装就算启用
                } else {
                    $pluginsList[$v["id"]]["status"] = 0;
                    // 调用失败没有
                }
            }
            $final_arr["result"] = $pluginsList;
        } else {
            $final_arr = logCallErrorMsg($final_arr, $checkResult);
        }
        return $final_arr;
    }

    /**
     * 回调插件 config 的方法
     * @param string $paramObj
     */
    public function callFunc($paramObj = "")
    {
        $dataObj = paramsObj();
        $dataObj->request = paramsObj();
        $dataObj->data = paramsObj();
        $dataObj->data->use_trans = false;
        $dataObj->result = array();

        $final_arr = logInit();
        if ($final_arr["error_no"] == 0) {
            $mixed = parseToArr($paramObj, "mixed", 0);
            $params = parseToArr($paramObj, "params", array());
            $messages = parseToArr($paramObj, "messages", array());
            $rules = array(
                'pluginId' => 'require',
                'action' => 'require',
                'className' => '',
            );
            $dataDefault = array();
            $dataDefault["className"] = "config";
            $paramsObj = paramsObj();
            $paramsObj->params = $params;
            $paramsObj->mixed = $mixed;
            $paramsObj->rules = $rules;
            $paramsObj->messages = $messages;
            $paramsObj->dataDefault = $dataDefault;
            $checkResult = app("verifyParam")::validatorRequest($paramsObj);
            if ($checkResult["error_no"] == 0) {
                $dataObj->request = $checkResult["result"];
            } else {
                $final_arr = logCallErrorMsg($final_arr, $checkResult);
            }
        }
        if ($final_arr["error_no"] == 0) {
            $action = $dataObj->request->action;
            $className = $dataObj->request->className;
            $classNamespace = $dataObj->request->pluginId . "/{$className}";
            $classNamespace = str_replace("/", "\\", $classNamespace);
            if (class_exists($classNamespace)) {
                $controllerObj = new $classNamespace;
                if (method_exists($controllerObj, $action)) {
                    $final_arr["result"] = $controllerObj->$action();
                } else {
                    $final_arr = recordLogMsgLevelTwo(app("errorLevel")::E_WARNING, app("errorCode")::OPEN_FAIL, lang("sys.openFail"));
                }
            } else {
                //$final_arr = recordLogMsgLevelTwo(app("errorLevel")::E_WARNING, app("errorCode")::OPEN_FAIL, lang("sys.openFail"));
            }
        }
        return $final_arr;
    }

    /**
     * 删除插件缓存
     * @param string $paramObj
     */
    public function deletePluginsCache($paramObj = "")
    {
        $final_arr = logInit();
        if ($final_arr["error_no"] == 0) {
            $pluginsSettingPath = runtimePath("cache/plugin") . "all.json";
            if (is_file($pluginsSettingPath)) {
                fileDel($pluginsSettingPath);
            } else {
                //不存在失败忽略
            }
        }
        return $final_arr;
    }

    /**
     * 取插件状态 传入插件路径
     * @param string $paramObj
     */
    public function getPluginsStatus($paramObj = "")
    {
        $dataObj = getParamsObj();
        $final_arr = logInit();
        if ($final_arr["error_no"] == 0) {
            $mixed = 1;
            $params = parseToArr($paramObj, "params", array());
            $rules = array(
                'pluginId' => 'require',
            );

            $paramsObj = paramsObj();
            $paramsObj->params = $params;
            $paramsObj->mixed = $mixed;
            $paramsObj->rules = $rules;
            $paramsObj->messages = getValidateMessage($rules);
            $checkResult = app("verifyParam")::validatorRequest($paramsObj);
            if ($checkResult["error_no"] == 0) {
                $dataObj->request = $checkResult["result"];
            } else {
                $final_arr = logCallErrorMsg($final_arr, $checkResult);
            }
        }

        if ($final_arr["error_no"] == 0) {
            $tempObj = getParamsObj();
            $tempObj->params["pluginId"] = $dataObj->request->pluginId;
            $tempObj->params["action"] = "info";
            $result = $this->callFunc($tempObj);
            if ($result["error_no"] == 0) {
                $final_arr["result"] = $result["result"];
            } else {
                $final_arr = logCallErrorMsg($final_arr, $result);
            }
        }


        return $final_arr;
    }

    public function __call($name, $arguments)
    {
        return recordLogMsgLevelTwo(app("errorLevel")::E_WARNING, app("errorCode")::UNDEFINED_METHOD, lang("sys.noMethodDefined"), $name, $arguments);
    }
}